package com.cx.simpleweb.config;

import com.cx.simpleweb.filter.GateWayFilter;
import com.cx.simpleweb.filter.LoginFilter;
import com.cx.simpleweb.service.MyUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.DefaultLoginPageConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService (new MyUserDetailsService ()).passwordEncoder (NoOpPasswordEncoder.getInstance ());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

//        http.authorizeRequests (authorize -> authorize.antMatchers ("/gw").hasRole("USER"))
//        .formLogin (formLogin -> formLogin.failureForwardUrl ("/login.html").loginPage ("/login.html"));
        GateWayRequestMatcher gateWayRequestMatcher = new GateWayRequestMatcher ()
                .addMatcherUrl ("/gw")
                .addService ("gotest","USER")
                .addService ("login");
        GateWayFilter filterSecurityInterceptor = new GateWayFilter (gateWayRequestMatcher);
        List<AccessDecisionVoter<?>> list = new ArrayList<> ();
        RoleVoter roleVoter = new RoleVoter ();
        list.add (roleVoter);
        AffirmativeBased affirmativeBased = new AffirmativeBased (list);
        filterSecurityInterceptor.setAccessDecisionManager (affirmativeBased);
        filterSecurityInterceptor.setSecurityMetadataSource (new FilterInvocationSecurityMetadataSource (){


            @Override
            public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
                GateWayRequestMatcher requestMatcher = (GateWayRequestMatcher) filterSecurityInterceptor.getRequestMatcher ();
                return requestMatcher.getCurrentConfigAttribute ();
            }

            @Override
            public Collection<ConfigAttribute> getAllConfigAttributes() {
                GateWayRequestMatcher requestMatcher = (GateWayRequestMatcher) filterSecurityInterceptor.getRequestMatcher ();
                return requestMatcher.getAllConfigAttributes();
            }

            @Override
            public boolean supports(Class<?> clazz) {
                return true;
            }

        });

        filterSecurityInterceptor.afterPropertiesSet ();
        http
                .csrf().disable ()
//                .authorizeRequests ().anyRequest().authenticated()




                .requestMatcher (gateWayRequestMatcher)
                .addFilter (filterSecurityInterceptor)
                .addFilterAfter (new LoginFilter (authenticationManager (),gateWayRequestMatcher,"login"),GateWayFilter.class)
                .authorizeRequests (authorize -> authorize.antMatchers ("/gw").hasRole("USER"))
//                .formLogin (formLogin -> formLogin.failureForwardUrl ("/login.html").loginPage ("/login.html"))


        ;


    }

}
